package ttelectronic.mobileholder.core;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.android.internal.telephony.ITelephony;

import ttelectronic.mobileholder.R;
import ttelectronic.mobileholder.common.MHCommon;
import ttelectronic.mobileholder.dataaccess.MHDataBaseWrapper;
import ttelectronic.mobileholder.dataaccess.MHPinObject;
import ttelectronic.mobileholder.service.MHAutoConnectionService;
import ttelectronic.mobileholder.service.MHBluetoothConnectingService;
import android.app.Activity;
import android.app.NotificationManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MHMainActivity extends Activity {

	// View
	private TextView mtvStatus;
	private TextView tvBateryLevel;
	private TextView tvMissCall;
	private TextView tvUnReadMessage;
	private Button mbtnStartService;
	// private Intent mItent;
	private Context mContext;
	private NotificationManager mNotificationManager;

	// Notification bar
	private static final int NOTIFICATION_ICON = 1;
	private static final int REQUEST_ENABLE_BT = 2;

	// Bluetooth
	private BluetoothAdapter mBluetoothAdapter;
	private MHBluetoothConnectingService mConnectingService;
	private String mConnectedDeviceName;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mContext = getApplicationContext();

		MHDataBaseWrapper database = new MHDataBaseWrapper(this);
		try {
			database.addPin(new MHPinObject(1, MHCommon.PIN_CONFIGURATION,
					MHCommon.TEM_CONFIGURATION));
			if (database.getPin() != null) {
				synchronized (this) {
					MHCommon.PIN_CONFIGURATION = database.getPin()
							.getPinLevel();
					MHCommon.TEM_CONFIGURATION = database.getPin()
							.getTemLevel();
					Log.d(MHCommon.TAG + "Pin", database.getPin().getPinLevel()
							+ " || " + database.getPin().getTemLevel());
				}
			} else
				Log.d(MHCommon.TAG + "Pin", "null");
		} catch (Exception e) {
			Log.d(MHCommon.TAG + "Error", "Cannot insert pin");
		}

		// VIEW
		mtvStatus = (TextView) findViewById(R.id.tvStatus);
		tvBateryLevel = (TextView) findViewById(R.id.tvBateryLevel);
		tvMissCall = (TextView) findViewById(R.id.tvMissCall);
		tvUnReadMessage = (TextView) findViewById(R.id.tvUnreadMessage);

		mbtnStartService = (Button) findViewById(R.id.btnStartService);
		mbtnStartService.setOnClickListener(doStartService);
		// mbtnStopService = (Button) findViewById(R.id.btnStopService);

		// Bluetooth connection
		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		if (!checkBluetoothState())
			startBluetooth();
	}

	@Override
	public void onStart() {
		super.onStart();
		if (mConnectingService == null)
			mConnectingService = new MHBluetoothConnectingService(this,
					mHandler);
		MHAutoConnectionService t = new MHAutoConnectionService(mContext,
				mBluetoothAdapter, mHandler);
		t.start();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.optMenuSetting:
			synchronized (this) {
				MHCommon.BLUETOOTH_STATUS = false;
			}
			Intent serverIntent = new Intent(this, MHListDeviceActivity.class);
			startActivityForResult(serverIntent, MHCommon.CHOOSE_DEVICE);
			break;
		case R.id.optMenuExit:
			this.finish();
			System.exit(0);
			break;
		case R.id.optPinSetting:
			Intent i = new Intent(this, MHPinSettingActivity.class);
			startActivity(i);
			break;
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case MHCommon.CHOOSE_DEVICE:
			if (resultCode == Activity.RESULT_OK) {
				String address = data.getExtras().getString(
						MHCommon.EXTRA_DEVICE_MAC_ADDRESS);
				BluetoothDevice device = mBluetoothAdapter
						.getRemoteDevice(address);
				doConnectDevice(device);
			}
			break;
		default:
			break;
		}
	}

	private void doConnectDevice(BluetoothDevice device) {
		mConnectingService.connect(device);
	}

	private OnClickListener doStartService = new OnClickListener() {
		@Override
		public void onClick(View v) {

		}
	};

	private boolean checkBluetoothState() {
		if (mBluetoothAdapter == null) {
			mtvStatus.setText("Bluetooth NOT support");
			return true;
		} else {
			if (mBluetoothAdapter.isEnabled())
				return true;
		}
		return false;
	}

	public void startBluetooth() {
		Intent enableBtIntent = new Intent(
				BluetoothAdapter.ACTION_REQUEST_ENABLE);
		startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
	}

	// The Handler that gets information back from the
	// MHBluetoothConnectingService
	private final Handler mHandler = new Handler() {
		@SuppressWarnings({ "unchecked", "rawtypes" })
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MHCommon.MESSAGE_STATE_CHANGE:
				switch (msg.arg1) {
				case MHCommon.STATE_CONNECTED:
					Log.d(MHCommon.TAG, "Connected with...");
					synchronized (this) {
						MHCommon.BLUETOOTH_STATUS = true;
					}
					break;
				case MHCommon.STATE_CONNECTING:
					mtvStatus.setText("connecting...");
					synchronized (this) {
						MHCommon.BLUETOOTH_STATUS = true;
					}
					break;
				case MHCommon.STATE_LISTEN:
					mtvStatus.setText("Listen...");
					synchronized (this) {
						MHCommon.BLUETOOTH_STATUS = false;
					}
					break;
				case MHCommon.STATE_NONE:
					synchronized (this) {
						MHCommon.BLUETOOTH_STATUS = false;
					}
					mtvStatus.setText("NOT connected");
					break;
				}
				break;

			case MHCommon.MESSAGE_READ:
				byte[] readBuf = (byte[]) msg.obj;
				if (readBuf[0] == 54) {
					Log.d(MHCommon.TAG, "Number 6");
					if (MHCommon.PHONE_STATE == 0) {
						enableSpeakerPhone(mContext, true);
						try {
							answerPhoneAidl(mContext);
							enableSpeakerPhone(mContext, true);
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
							answerPhoneHeadsethook(mContext);
							enableSpeakerPhone(mContext, true);
						}
						synchronized (this) {
							MHCommon.PHONE_STATE = 1;
						}

					} else {
						// enableSpeakerPhone(mContext, false);
						endCall(mContext);
					}

					break;
				} else if (readBuf[0] == 55) {
					Intent intent = new Intent(
							"android.intent.action.MUSIC_PLAYER");
					startActivity(intent);
					break;
				} else if (readBuf[0] == 56) {
					Ringtone ringtone = RingtoneManager.getRingtone(mContext,
							Settings.System.DEFAULT_RINGTONE_URI);
					ringtone.play();
					Log.d(MHCommon.TAG + "Ringtone", "ringtone");
					break;
				} else if (readBuf[0] == 57) {
					Log.d(MHCommon.TAG + "re-call", "recall");
					String[] strFields = {
							android.provider.CallLog.Calls.NUMBER,
							android.provider.CallLog.Calls.TYPE,
							android.provider.CallLog.Calls.CACHED_NAME,
							android.provider.CallLog.Calls.CACHED_NUMBER_TYPE };
					String strOrder = android.provider.CallLog.Calls.DATE
							+ " DESC";
					Cursor mCallCursor = getContentResolver().query(
							android.provider.CallLog.Calls.CONTENT_URI,
							strFields, null, null, strOrder);
					if (mCallCursor.moveToFirst()) {
						String lastNumber = mCallCursor.getString(0);
						String uri = "tel:" + lastNumber.trim();
						Intent intent = new Intent(Intent.ACTION_CALL);
						intent.setData(Uri.parse(uri));
						startActivity(intent);
					}
				}
				break;

			case MHCommon.MESSAGE_DEVICE_NAME:
				mConnectedDeviceName = msg.getData().getString(
						MHCommon.DEVICE_NAME);
				mtvStatus.setText(mConnectedDeviceName);
				synchronized (this) {
					MHCommon.BLUETOOTH_STATUS = true;
				}
				break;

			case MHCommon.MESSAGE_BATERY_LEVEL:
				String bateryLevel = msg.getData().getString(
						MHCommon.BUNDLE_BATERY_LEVEL);
				tvBateryLevel.setText(bateryLevel);
				break;

			case MHCommon.MESSAGE_MISS_CALL:
				String missCall = msg.getData().getString(
						MHCommon.BUNDLE_MISS_CALL);
				tvMissCall.setText(missCall);
				break;

			case MHCommon.MESSAGE_SMS:
				String sms = msg.getData().getString(MHCommon.BUNDLE_SMS);
				tvUnReadMessage.setText(sms);
				break;

			case MHCommon.MESSAGE_AUTOCONNECTION:
				Log.d(MHCommon.TAG, "Come here");
				synchronized (this) {
					MHCommon.BLUETOOTH_STATUS = true;
				}
				String mac = msg.getData().getString(
						MHCommon.BUNDLE_MAC_ADDRESS);
				doConnectDevice(mBluetoothAdapter.getRemoteDevice(mac));
				break;

			default:
				break;
			}
		}
	};

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (Integer.parseInt(android.os.Build.VERSION.SDK) < 5
				&& keyCode == KeyEvent.KEYCODE_BACK
				&& event.getRepeatCount() == 0) {
			Log.d(MHCommon.TAG + "MHMainActivity", "onKeyDown Called");
			onBackPressed();
		}
		return super.onKeyDown(keyCode, event);
	}

	public void onBackPressed() {
		Log.d(MHCommon.TAG + "MHMainActivity", "onBackPressed Called");
		Intent setIntent = new Intent(Intent.ACTION_MAIN);
		setIntent.addCategory(Intent.CATEGORY_HOME);
		setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(setIntent);
		return;
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		this.startActivity(new Intent(this, MHMainActivity.class));
	}

	private void enableSpeakerPhone(Context context, boolean status) {
		AudioManager audioManager = (AudioManager) context
				.getSystemService(Context.AUDIO_SERVICE);
		audioManager.setSpeakerphoneOn(status);
	}

	@SuppressWarnings("unchecked")
	private void answerPhoneAidl(Context context) throws Exception {
		// Set up communication with the telephony service (thanks to Tedd's
		// Droid Tools!)
		TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		Class c = Class.forName(tm.getClass().getName());
		Method m = c.getDeclaredMethod("getITelephony");
		m.setAccessible(true);
		ITelephony telephonyService;
		telephonyService = (ITelephony) m.invoke(tm);
		// Silence the ringer and answer the call!
		telephonyService.silenceRinger();
		telephonyService.answerRingingCall();
	}

	private void endCall(Context context) {
		TelephonyManager telephonyManager = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		Class clazz;
		try {
			clazz = Class.forName(telephonyManager.getClass().getName());
			Method method = clazz.getDeclaredMethod("getITelephony");
			method.setAccessible(true);
			ITelephony telephonyService = (ITelephony) method
					.invoke(telephonyManager);
			telephonyService.endCall();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	private void answerPhoneHeadsethook(Context context) {
		// Simulate a press of the headset button to pick up the call
		Intent buttonDown = new Intent(Intent.ACTION_MEDIA_BUTTON);
		buttonDown.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(
				KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));
		context.sendOrderedBroadcast(buttonDown,
				"android.permission.CALL_PRIVILEGED");

		// froyo and beyond trigger on buttonUp instead of buttonDown
		Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);
		buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(
				KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
		context.sendOrderedBroadcast(buttonUp,
				"android.permission.CALL_PRIVILEGED");
	}
}
